package com.yeziji.dataCenter.business.record.service.impl;

import com.yeziji.annotation.RedisLock;
import com.yeziji.common.IServiceImpl;
import com.yeziji.dataCenter.business.record.entity.DataCenterMaxIdRecordEntity;
import com.yeziji.dataCenter.business.record.entity.table.DataCenterMaxIdRecordTableDef;
import com.yeziji.dataCenter.business.record.mapper.DataCenterMaxIdRecordMapper;
import com.yeziji.dataCenter.business.record.service.DataCenterMaxIdRecordService;
import com.yeziji.dataCenter.common.DataCenterKey;
import com.yeziji.dataCenter.constant.DataCenterMaxIdTypeEnum;
import com.yeziji.devops.annotation.DevopsService;
import com.yeziji.devops.common.DevopsKey;
import org.springframework.stereotype.Service;

import java.util.Optional;

/**
 * 数据中心最大 id 记录表 服务层实现。
 *
 * @author system
 * @since 2024-10-26
 */
@Service
@DevopsService(name = DevopsKey.DataSource.MASTER)
public class DataCenterMaxIdRecordServiceImpl extends IServiceImpl<DataCenterMaxIdRecordMapper, DataCenterMaxIdRecordEntity> implements DataCenterMaxIdRecordService {
    private static final DataCenterMaxIdRecordTableDef MAX_ID_RECORD_TABLE_DEF = DataCenterMaxIdRecordTableDef.DATA_CENTER_MAX_ID_RECORD;

    @Override
    @RedisLock(lockKey = DataCenterKey.Redis.GET_MAX_ID_RECORD_LOCK, concatArgs = true, fieldName = "code", isObject = true)
    public int getAsMaxIdByType(DataCenterMaxIdTypeEnum typeEnum) {
        return this.queryChain()
                .select(MAX_ID_RECORD_TABLE_DEF.MAX_ID.as("maxId")) // 这里不知道为什么 linux 中会返回 null...
                .eq(DataCenterMaxIdRecordEntity::getType, typeEnum.getCode())
                .oneOpt()
                .map(DataCenterMaxIdRecordEntity::getMaxId)
                .orElse(0);
    }

    @Override
    @RedisLock(lockKey = DataCenterKey.Redis.GET_MAX_ID_UPDATE_LOCK, concatArgs = true, fieldName = "code", isObject = true)
    public boolean increaseByType(DataCenterMaxIdTypeEnum typeEnum) {
        Optional<Integer> maxIdOpt = this.queryChain()
                .select(MAX_ID_RECORD_TABLE_DEF.MAX_ID)
                .eq(DataCenterMaxIdRecordEntity::getType, typeEnum.getCode())
                .oneAsOpt(Integer.class);
        if (maxIdOpt.isPresent()) {
            return this.updateChain().setRaw(DataCenterMaxIdRecordEntity::getMaxId, "max_id + 1").update();
        } else {
            return this.save(new DataCenterMaxIdRecordEntity(1, typeEnum.getCode()));
        }
    }

    @Override
    @RedisLock(lockKey = DataCenterKey.Redis.GET_MAX_ID_UPDATE_LOCK, concatArgs = true, fieldName = "code", isObject = true)
    public boolean decreaseByType(DataCenterMaxIdTypeEnum typeEnum) {
        Optional<Integer> maxIdOpt = this.queryChain()
                .select(MAX_ID_RECORD_TABLE_DEF.MAX_ID)
                .eq(DataCenterMaxIdRecordEntity::getType, typeEnum.getCode())
                .oneAsOpt(Integer.class);
        if (maxIdOpt.isPresent()) {
            return this.updateChain().setRaw(DataCenterMaxIdRecordEntity::getMaxId, "max_id - 1").update();
        }
        return false;
    }
}
